home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
- common.c
- **********************************************************************/
- /**********************************************************************
- * MPEG/audio coding/decoding software, work in progress *
- * NOT for public distribution until verified and approved by the *
- * MPEG/audio committee. For further information, please contact *
- * Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com *
- * *
- * VERSION 4.0 *
- * changes made since last update: *
- * date programmers comment *
- * 2/25/91 Doulas Wong, start of version 1.0 records *
- * Davis Pan *
- * 5/10/91 W. Joseph Carter Created this file for all common *
- * functions and global variables. *
- * Ported to Macintosh and Unix. *
- * Added Jean-Georges Fritsch's *
- * "bitstream.c" package. *
- * Added routines to handle AIFF PCM *
- * sound files. *
- * Added "mem_alloc()" and "mem_free()" *
- * routines for memory allocation *
- * portability. *
- * Added routines to convert between *
- * Apple SANE extended floating point *
- * format and IEEE double precision *
- * floating point format. For AIFF. *
- * 02jul91 dpwe (Aware Inc) Moved allocation table input here; *
- * Tables read from subdir TABLES_PATH. *
- * Added some debug printout fns (Write*)*
- * 7/10/91 Earle Jennings replacement of the one float by FLOAT *
- * port to MsDos from MacIntosh version *
- * 8/ 5/91 Jean-Georges Fritsch fixed bug in open_bit_stream_r() *
- *10/ 1/91 S.I. Sudharsanan, Ported to IBM AIX platform. *
- * Don H. Lee, *
- * Peter W. Farrett *
- *10/3/91 Don H. Lee implemented CRC-16 error protection *
- * newly introduced functions are *
- * I_CRC_calc, II_CRC_calc and *
- * update_CRC. Additions and revisions *
- * are marked with dhl for clarity *
- *10/18/91 Jean-Georges Fritsch fixed bug in update_CRC(), *
- * II_CRC_calc() and I_CRC_calc() *
- * 2/11/92 W. Joseph Carter Ported new code to Macintosh. Most *
- * important fixes involved changing *
- * 16-bit ints to long or unsigned in *
- * bit alloc routines for quant of 65535 *
- * and passing proper function args. *
- * Removed "Other Joint Stereo" option *
- * and made bitrate be total channel *
- * bitrate, irrespective of the mode. *
- * Fixed many small bugs & reorganized. *
- * 3/20/92 Jean-Georges Fritsch fixed bug in start-of-frame search *
- * 6/15/92 Juan Pineda added refill_buffer(bs) "n" *
- * initialization *
- * 7/08/92 Susanne Ritscher MS-DOS, MSC6.0 port fixes *
- * 7/27/92 Mike Li (re-)Port to MS-DOS *
- * 8/19/92 Soren H. Nielsen Fixed bug in I_CRC_calc and in *
- * II_CRC_calc. Added function: new_ext *
- * for better MS-DOS compatability *
- * 3/10/93 Kevin Peterson changed aiff_read_headers to handle *
- * chunks in any order. now returns *
- * position of sound data in file. *
- * 3/31/93 Jens Spille changed IFF_* string compares to use *
- * strcmp() *
- * 5/30/93 Masahiro Iwadare ?? the previous modification does not *
- * work. recovered to the original. ?? *
- * 8/27/93 Seymour Shlien, Fixes in Unix and MSDOS ports, *
- * Daniel Lauzon, and *
- * Bill Truerniet *
- **********************************************************************/
-
- /***********************************************************************
- *
- * Global Include Files
- *
- ***********************************************************************/
-
- #include "common.h"
-
- #ifdef MACINTOSH
-
- #include <SANE.h>
- #include <pascal.h>
-
- #endif
-
- #include <ctype.h>
- #include "audio.h"
-
- /***********************************************************************
- *
- * Global Variable Definitions
- *
- ***********************************************************************/
-
- char *mode_names[4] = { "stereo", "j-stereo", "dual-ch", "single-ch" };
- char *layer_names[3] = { "I", "II", "III" };
-
- double s_freq[4] = {44.1, 48, 32, 0};
-
- int bitrate[3][15] = {
- {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
- {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
- {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}
- };
-
- double FAR multiple[64] = {
- 2.00000000000000, 1.58740105196820, 1.25992104989487,
- 1.00000000000000, 0.79370052598410, 0.62996052494744, 0.50000000000000,
- 0.39685026299205, 0.31498026247372, 0.25000000000000, 0.19842513149602,
- 0.15749013123686, 0.12500000000000, 0.09921256574801, 0.07874506561843,
- 0.06250000000000, 0.04960628287401, 0.03937253280921, 0.03125000000000,
- 0.02480314143700, 0.01968626640461, 0.01562500000000, 0.01240157071850,
- 0.00984313320230, 0.00781250000000, 0.00620078535925, 0.00492156660115,
- 0.00390625000000, 0.00310039267963, 0.00246078330058, 0.00195312500000,
- 0.00155019633981, 0.00123039165029, 0.00097656250000, 0.00077509816991,
- 0.00061519582514, 0.00048828125000, 0.00038754908495, 0.00030759791257,
- 0.00024414062500, 0.00019377454248, 0.00015379895629, 0.00012207031250,
- 0.00009688727124, 0.00007689947814, 0.00006103515625, 0.00004844363562,
- 0.00003844973907, 0.00003051757813, 0.00002422181781, 0.00001922486954,
- 0.00001525878906, 0.00001211090890, 0.00000961243477, 0.00000762939453,
- 0.00000605545445, 0.00000480621738, 0.00000381469727, 0.00000302772723,
- 0.00000240310869, 0.00000190734863, 0.00000151386361, 0.00000120155435,
- 1E-20
- };
-
- struct alloc_entry
- {
- unsigned int steps;
- unsigned int bits;
- unsigned int group;
- unsigned int quant;
- };
-
- #include "tables/alloc_0.h"
- #include "tables/alloc_1.h"
- #include "tables/alloc_2.h"
- #include "tables/alloc_3.h"
-
- /***********************************************************************
- *
- * Global Function Definitions
- *
- ***********************************************************************/
-
- /* The system uses a variety of data files. By opening them via this
- function, we can accommodate various locations. */
-
- /***********************************************************************
- /*
- /* Read one of the data files ("alloc_*") specifying the bit allocation/
- /* quatization parameters for each subband in layer II encoding
- /*
- /**********************************************************************/
-
- /***********************************************************************
- /*
- /* Using the decoded info the appropriate possible quantization per
- /* subband table is loaded
- /*
- /**********************************************************************/
-
- int pick_table(fr_ps) /* choose table, load if necess, return # sb's */
- frame_params *fr_ps;
- {
- int table, lay, ws, bsp, br_per_ch, sfrq;
- int sblim = fr_ps->sblimit; /* return current value if no load */
-
- lay = fr_ps->header->lay - 1;
- bsp = fr_ps->header->bitrate_index;
- br_per_ch = bitrate[lay][bsp] / fr_ps->stereo;
- ws = fr_ps->header->sampling_frequency;
- sfrq = s_freq[ws];
- /* decision rules refer to per-channel bitrates (kbits/sec/chan) */
- if ((sfrq == 48 && br_per_ch >= 56) ||
- (br_per_ch >= 56 && br_per_ch <= 80)) table = 0;
- else if (sfrq != 48 && br_per_ch >= 96) table = 1;
- else if (sfrq != 32 && br_per_ch <= 48) table = 2;
- else table = 3;
- if (fr_ps->tab_num != table) {
-
- switch((fr_ps->tab_num = table))
- {
- default:
- case 0:
- printf("using bit-allocation table 0.\n");
- fr_ps->alloc = (al_table *)&t_alloc_0;
- sblim = 27;
- break;
- case 1:
- printf("using bit-allocation table 1.\n");
- fr_ps->alloc = (al_table *)&t_alloc_1;
- sblim = 30;
- break;
- case 2:
- printf("using bit-allocation table 2.\n");
- fr_ps->alloc = (al_table *)&t_alloc_2;
- sblim = 8;
- break;
- case 3:
- printf("using bit-allocation table 3.\n");
- fr_ps->alloc = (al_table *)&t_alloc_3;
- sblim = 12;
- break;
- }
- }
- return sblim;
- }
-
- int js_bound(lay, m_ext)
- int lay, m_ext;
- {
- static int jsb_table[3][4] = { { 4, 8, 12, 16 }, { 4, 8, 12, 16},
- { 0, 4, 8, 16} }; /* lay+m_e -> jsbound */
-
- if(lay<1 || lay >3 || m_ext<0 || m_ext>3) {
- fprintf(stderr, "js_bound bad layer/modext (%d/%d)\n", lay, m_ext);
- exit(1);
- }
- return(jsb_table[lay-1][m_ext]);
- }
-
- void hdr_to_frps(fr_ps) /* interpret data in hdr str to fields in fr_ps */
- frame_params *fr_ps;
- {
- layer *hdr = fr_ps->header; /* (or pass in as arg?) */
-
- fr_ps->actual_mode = hdr->mode;
- fr_ps->stereo = (hdr->mode == MPG_MD_MONO) ? 1 : 2;
- if (hdr->lay == 2) fr_ps->sblimit = pick_table(fr_ps);
- else fr_ps->sblimit = SBLIMIT;
- if(hdr->mode == MPG_MD_JOINT_STEREO)
- fr_ps->jsbound = js_bound(hdr->lay, hdr->mode_ext);
- else
- fr_ps->jsbound = fr_ps->sblimit;
- /* alloc, tab_num set in pick_table */
- }
-
- /*******************************************************************************
- *
- * Allocate number of bytes of memory equal to "block".
- *
- *******************************************************************************/
-
- void FAR *mem_alloc(block, item)
- unsigned long block;
- char *item;
- {
-
- void *ptr;
-
- #ifdef MACINTOSH
- ptr = NewPtr(block);
- #endif
-
- #ifdef MSC60
- /*ptr = (void FAR *) _fmalloc((unsigned int)block);*/ /* far memory, 92-07-08 sr */
- ptr = (void FAR *) malloc((unsigned int)block); /* far memory, 93-08-24 ss */
- #endif
-
- #if ! defined (MACINTOSH) && ! defined (MSC60)
- ptr = (void FAR *) malloc(block);
- #endif
-
- if (ptr != NULL){
- #ifdef MSC60
- _fmemset(ptr, 0, (unsigned int)block); /* far memory, 92-07-08 sr */
- #else
- memset(ptr, 0, block);
- #endif
- }
- else{
- printf("Unable to allocate %s\n", item);
- exit(0);
- }
- return(ptr);
- }
-
-
- /****************************************************************************
- *
- * Free memory pointed to by "*ptr_addr".
- *
- *****************************************************************************/
-
- void mem_free(ptr_addr)
- void **ptr_addr;
- {
-
- if (*ptr_addr != NULL){
- #ifdef MACINTOSH
- DisposPtr(*ptr_addr);
- #else
- free(*ptr_addr);
- #endif
- *ptr_addr = NULL;
- }
-
- }
-
- /*******************************************************************************
- *
- * Check block of memory all equal to a single byte, else return FALSE
- *
- *******************************************************************************/
-
- int memcheck(array, test, num)
- char *array;
- int test; /* but only tested as a char (bottom 8 bits) */
- int num;
- {
- int i=0;
-
- while (array[i] == test && i<num) i++;
- if (i==num) return TRUE;
- else return FALSE;
- }
-
- /****************************************************************************
- *
- * Routines to convert between the Apple SANE extended floating point format
- * and the IEEE double precision floating point format. These routines are
- * called from within the Audio Interchange File Format (AIFF) routines.
- *
- *****************************************************************************/
-
- /*
- *** Apple's 80-bit SANE extended has the following format:
-
- 1 15 1 63
- +-+-------------+-+-----------------------------+
- |s| e |i| f |
- +-+-------------+-+-----------------------------+
- msb lsb msb lsb
-
- The value v of the number is determined by these fields as follows:
- If 0 <= e < 32767, then v = (-1)^s * 2^(e-16383) * (i.f).
- If e == 32767 and f == 0, then v = (-1)^s * (infinity), regardless of i.
- If e == 32767 and f != 0, then v is a NaN, regardless of i.
-
- *** IEEE Draft Standard 754 Double Precision has the following format:
-
- MSB
- +-+---------+-----------------------------+
- |1| 11 Bits | 52 Bits |
- +-+---------+-----------------------------+
- ^ ^ ^
- | | |
- Sign Exponent Mantissa
- */
-
- /**** for debugging
- showchar(str)
- char str[4];
- {
- int i;
- for (i=0;i<4;i++) printf("%c",str[i]);
- printf("\n");
- }
- ****/
-
- /*****************************************************************************
- *
- * bit_stream.c package
- * Author: Jean-Georges Fritsch, C-Cube Microsystems
- *
- *****************************************************************************/
-
- /********************************************************************
- This package provides functions to write (exclusive or read)
- information from (exclusive or to) the bit stream.
-
- If the bit stream is opened in read mode only the get functions are
- available. If the bit stream is opened in write mode only the put
- functions are available.
- ********************************************************************/
-
- /*open_bit_stream_r(); open the device to read the bit stream from it */
- /*close_bit_stream(); close the device containing the bit stream */
- /*alloc_buffer(); open and initialize the buffer; */
- /*desalloc_buffer(); empty and close the buffer */
- /*unsigned int get1bit(); read 1 bit from the bit stream */
- /*unsigned long getbits(); read N bits from the bit stream */
- /*unsigned long look_ahead(); grep the next N bits in the bit stream without*/
- /* changing the buffer pointer */
- /*unsigned long sstell(); return the current bit stream length (in bits) */
- /*int seek_sync(); return 1 if a sync word was found in the bit stream */
- /* otherwise returns 0 */
-
- #ifndef __PPC__
- /* refill the buffer from the input device when the buffer becomes empty */
- void refill_buffer(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- register int i=bs->buf_size-2-bs->buf_byte_idx;
- register unsigned long n=1;
- register int index=0;
- char val[2];
-
- while ((i>=0) && (!bs->eob))
- bs->buf[i--] = audio_pollbuffer();
- }
- #endif
-
- static char *he = "0123456789ABCDEF";
-
-
- /* open the device to read the bit stream from it */
- void open_bit_stream_r(bs, bs_filenam, size)
- Bit_stream_struc *bs; /* bit stream structure */
- char *bs_filenam; /* name of the bit stream file */
- int size; /* size of the buffer */
- {
- bs->format = BINARY;
- alloc_buffer(bs, size);
- bs->buf_byte_idx=0;
- bs->buf_bit_idx=0;
- bs->totbit=0;
- bs->mode = READ_MODE;
- bs->eob = FALSE;
- bs->eobs = FALSE;
- }
-
- /*close the device containing the bit stream after a read process*/
- void close_bit_stream_r(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- desalloc_buffer(bs);
- }
-
- /*close the device containing the bit stream after a write process*/
- void close_bit_stream_w(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- desalloc_buffer(bs);
- }
-
- /*open and initialize the buffer; */
- void alloc_buffer(bs, size)
- Bit_stream_struc *bs; /* bit stream structure */
- int size;
- {
- bs->buf = (unsigned char FAR *) mem_alloc(size*sizeof(unsigned
- char), "buffer");
- bs->buf_size = size;
- }
-
- /*empty and close the buffer */
- void desalloc_buffer(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- free(bs->buf);
- }
-
- int putmask[9]={0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff};
- int clearmask[9]={0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x0};
-
- int mask[8]={0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
-
- #ifndef __PPC__
- /*read 1 bit from the bit stream */
- unsigned int get1bit(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- unsigned int bit;
- register int i;
-
- bs->totbit++;
-
- if (!bs->buf_bit_idx) {
- bs->buf_bit_idx = 8;
- bs->buf_byte_idx--;
- if ((bs->buf_byte_idx < MINIMUM) || (bs->buf_byte_idx < bs->eob)) {
- if (bs->eob)
- bs->eobs = TRUE;
- else {
- for (i=bs->buf_byte_idx; i>=0;i--)
- bs->buf[bs->buf_size-1-bs->buf_byte_idx+i] = bs->buf[i];
- refill_buffer(bs);
- bs->buf_byte_idx = bs->buf_size-1;
- }
- }
- }
- bit = bs->buf[bs->buf_byte_idx]&mask[bs->buf_bit_idx-1];
- bit = bit >> (bs->buf_bit_idx-1);
- bs->buf_bit_idx--;
- return(bit);
- }
- #endif
-
- /*look ahead for the next N bits from the bit stream */
- unsigned long look_ahead(bs, N)
- Bit_stream_struc *bs; /* bit stream structure */
- int N; /* number of bits to read from the bit stream */
- {
- unsigned long val=0;
- register int j = N;
- register int k, tmp;
- register int bit_idx = bs->buf_bit_idx;
- register int byte_idx = bs->buf_byte_idx;
-
- if (N > MAX_LENGTH)
- printf("Cannot read or write more than %d bits at a time.\n", MAX_LENGTH);
-
- while (j > 0) {
- if (!bit_idx) {
- bit_idx = 8;
- byte_idx--;
- }
- k = MIN (j, bit_idx);
- tmp = bs->buf[byte_idx]&putmask[bit_idx];
- tmp = tmp >> (bit_idx-k);
- val |= tmp << (j-k);
- bit_idx -= k;
- j -= k;
- }
- return(val);
- }
-
- #ifndef __PPC__
- /*read N bit from the bit stream */
- unsigned long getbits(bs, N)
- Bit_stream_struc *bs; /* bit stream structure */
- int N; /* number of bits to read from the bit stream */
- {
- unsigned long val=0;
- register int i;
- register int j = N;
- register int k, tmp;
-
- if (N > MAX_LENGTH)
- printf("Cannot read or write more than %d bits at a time.\n", MAX_LENGTH);
-
- bs->totbit += N;
- while (j > 0) {
- if (!bs->buf_bit_idx) {
- bs->buf_bit_idx = 8;
- bs->buf_byte_idx--;
- if ((bs->buf_byte_idx < MINIMUM) || (bs->buf_byte_idx < bs->eob)) {
- if (bs->eob)
- bs->eobs = TRUE;
- else {
- for (i=bs->buf_byte_idx; i>=0;i--)
- bs->buf[bs->buf_size-1-bs->buf_byte_idx+i] = bs->buf[i];
- refill_buffer(bs);
- bs->buf_byte_idx = bs->buf_size-1;
- }
- }
- }
- k = MIN (j, bs->buf_bit_idx);
- tmp = bs->buf[bs->buf_byte_idx]&putmask[bs->buf_bit_idx];
- tmp = tmp >> (bs->buf_bit_idx-k);
- val |= tmp << (j-k);
- bs->buf_bit_idx -= k;
- j -= k;
- }
- return(val);
- }
- #endif
-
- #if 0
- /*return the current bit stream length (in bits)*/
- unsigned long sstell(bs)
- Bit_stream_struc *bs; /* bit stream structure */
- {
- return(bs->totbit);
- }
- #endif
-
- /*this function seeks for a byte aligned sync word in the bit stream and
- places the bit stream pointer right after the sync.
- This function returns 1 if the sync was found otherwise it returns 0 */
- int seek_sync(bs, sync, N)
- Bit_stream_struc *bs; /* bit stream structure */
- long sync; /* sync word maximum 32 bits */
- int N; /* sync word length */
- {
- double pow();
- unsigned long aligning, stell();
- unsigned long val;
- long maxi = (int)pow(2.0, (FLOAT)N) - 1;
-
- aligning = sstell(bs)%ALIGNING;
- if (aligning)
- getbits(bs, (int)(ALIGNING-aligning));
-
- val = getbits(bs, N);
- while (((val&maxi) != sync) && (audioBufferSize>0)) {
- val <<= ALIGNING;
- val |= getbits(bs, ALIGNING);
- }
-
- if (!audioBufferSize) return(0);
- else return(1);
- }
- /*****************************************************************************
- *
- * End of bit_stream.c package
- *
- *****************************************************************************/
-
- /*****************************************************************************
- *
- * CRC error protection package
- *
- *****************************************************************************/
-
- void I_CRC_calc(fr_ps, bit_alloc, crc)
- frame_params *fr_ps;
- unsigned int bit_alloc[2][SBLIMIT];
- unsigned int *crc;
- {
- int i, k;
- layer *info = fr_ps->header;
- int stereo = fr_ps->stereo;
- int jsbound = fr_ps->jsbound;
-
- *crc = 0xffff; /* changed from '0' 92-08-11 shn */
- update_CRC(info->bitrate_index, 4, crc);
- update_CRC(info->sampling_frequency, 2, crc);
- update_CRC(info->padding, 1, crc);
- update_CRC(info->extension, 1, crc);
- update_CRC(info->mode, 2, crc);
- update_CRC(info->mode_ext, 2, crc);
- update_CRC(info->copyright, 1, crc);
- update_CRC(info->original, 1, crc);
- update_CRC(info->emphasis, 2, crc);
-
- for (i=0;i<SBLIMIT;i++)
- for (k=0;k<((i<jsbound)?stereo:1);k++)
- update_CRC(bit_alloc[k][i], 4, crc);
- }
-
- void II_CRC_calc(fr_ps, bit_alloc, scfsi, crc)
- frame_params *fr_ps;
- unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT];
- unsigned int *crc;
- {
- int i, k;
- layer *info = fr_ps->header;
- int stereo = fr_ps->stereo;
- int sblimit = fr_ps->sblimit;
- int jsbound = fr_ps->jsbound;
- al_table *alloc = fr_ps->alloc;
-
- *crc = 0xffff; /* changed from '0' 92-08-11 shn */
- update_CRC(info->bitrate_index, 4, crc);
- update_CRC(info->sampling_frequency, 2, crc);
- update_CRC(info->padding, 1, crc);
- update_CRC(info->extension, 1, crc);
- update_CRC(info->mode, 2, crc);
- update_CRC(info->mode_ext, 2, crc);
- update_CRC(info->copyright, 1, crc);
- update_CRC(info->original, 1, crc);
- update_CRC(info->emphasis, 2, crc);
-
- for (i=0;i<sblimit;i++)
- for (k=0;k<((i<jsbound)?stereo:1);k++)
- update_CRC(bit_alloc[k][i], (*alloc)[i][0].bits, crc);
-
- for (i=0;i<sblimit;i++)
- for (k=0;k<stereo;k++)
- if (bit_alloc[k][i])
- update_CRC(scfsi[k][i], 2, crc);
- }
-
- void update_CRC(data, length, crc)
- unsigned int data, length, *crc;
- {
- unsigned int masking, carry;
-
- masking = 1 << length;
-
- while((masking >>= 1)){
- carry = *crc & 0x8000;
- *crc <<= 1;
- if (!carry ^ !(data & masking))
- *crc ^= CRC16_POLYNOMIAL;
- }
- *crc &= 0xffff;
- }
-
- /*****************************************************************************
- *
- * End of CRC error protection package
- *
- *****************************************************************************/
-